
#include "csvlog.h"


csvlog_t* csvlog_create( char *fn, char *fmt )
{
	csvlog_t *cl=NULL;
	int cnt,i;
	char *fmt_ptr;
	int *pos_cnt=NULL, tmp_size;
	
	if (( fn == NULL ) || ( fmt == NULL ))
	{
		return NULL;
	}
	
	cl = malloc( sizeof( csvlog_t ) );
	if ( cl == NULL )
	{
		return NULL;
	}
	memset( cl, 0, sizeof( csvlog_t ) );
	
	//count number of delimeters
	cnt = 0;
	fmt_ptr = fmt;
	while ( fmt_ptr[0] != 0 )
	{
		if ( *fmt_ptr == ',' )
		{
			cnt += 1;
		}
		fmt_ptr += 1;
	}
	
	cl->opt_num = cnt+1;
	cl->options = malloc( sizeof(csvlog_line_t)*cl->opt_num );
	if ( cl->options == NULL )
	{
		return NULL;
	}
	memset( cl->options, 0, sizeof(csvlog_line_t)*cl->opt_num );
	
	pos_cnt = malloc( sizeof(int)*(cnt+2) );
	fmt_ptr = fmt;
	i = 0;
	while ( (fmt_ptr[0] != 0) && ( i < cnt ) )
	{
		if ( *fmt_ptr == ',' )
		{
			pos_cnt[i+1] = fmt_ptr-fmt;
			i += 1;
		}
		fmt_ptr += 1;
	}
	
	pos_cnt[0] = -1;
	pos_cnt[cnt+1] = strlen( fmt );
	
	for (i=1; i < cl->opt_num+1; i++)
	{
		tmp_size = pos_cnt[i] - pos_cnt[i-1] - 1;
		cl->options[i-1].option = malloc( sizeof(char)*(tmp_size+1) );
		memset( cl->options[i-1].option, 0, tmp_size+1 );
		memcpy( cl->options[i-1].option, fmt+pos_cnt[i-1]+1, tmp_size);
	}
	
	cl->file = fopen( fn, "w+" );
	free( pos_cnt );
	
	return cl;
}


int csvlog_set( csvlog_t *cl, char *opt , char *val )
{
	int i, str_size;
	if ( (cl == NULL) || (opt == NULL) || (val == NULL) )
	{
		return -1;
	}
	
	str_size = strlen( val );
	for ( i=0; i<cl->opt_num; i++)
	{
		if ((strlen( opt ) == strlen( cl->options[i].option )) && 
			(strcmp( opt, cl->options[i].option ) == 0) &&
			(cl->options[i].value == NULL))
		{
			cl->options[i].value = malloc( str_size+1 );
			memset( cl->options[i].value, 0, str_size+1 );
			memcpy( cl->options[i].value, val, str_size );
		}
	}
	return 0;
}

int csvlog_sets( csvlog_t *cl, char *opt, char *val )
{
	int i,j, cnt=0, ret, val_size,str_size;
	char *str=NULL;
	
	if ((cl == NULL) || (opt == NULL) || (val == NULL)) return -1;
	
	val_size = strlen( val ); 
	for ( i=0; i<val_size; i++ )
		if ( val[i] == '"' )
			cnt++;
	
	str_size = val_size + cnt + 2 + 1;
	str = malloc( str_size );
	if (str == NULL) return -1;
	memset( str, 0x0, str_size );
	
	if ( cnt != 0 )
	{
		str[0] = '"';
		i = 1;
		j = 0;
		while ( (i < (val_size + cnt + 2) ) && (j < val_size) )
		{
			if ( val[j] == '"' )
			{
				str[i] = '"';
				i += 1;
			}
			str[i] = val[j];
			i += 1;
			j += 1;
		}
		str[str_size - 2] = '"';
	} else
	{
		str[0]='"';
		for (i=0;i<val_size;i++)
			str[1+i] = val[i];
		str[str_size-2]='"';
	}
	ret = csvlog_set( cl, opt, str );
	free( str );
	return ret;
}



int csvlog_nl( csvlog_t *cl )
{
	int i;
	char *str=NULL;
	
	if ( cl == NULL )
	{
		return -1;
	}
	
	//create string that would be outputed
	// MAX_LOGSTR_LEN-1 used to set '\n' nezavisimo ot skoko infi budet vpihnuto
	str = malloc( MAX_LOGSTR_LEN );
	if (str == NULL)
		return -1;
	memset( str, 0, MAX_LOGSTR_LEN );
	
	for (i=0; i < cl->opt_num; i++ )
	{
		if ( cl->options[i].value != NULL )
		{
			strncat( str, cl->options[i].value, MAX_LOGSTR_LEN-1 );
		}
		if ( i != cl->opt_num-1 )
		{
			strncat( str, ",", MAX_LOGSTR_LEN-1 );
		}
	}
	
	strncat( str, "\n", MAX_LOGSTR_LEN );
	
	//write to the file
	fprintf( cl->file, "%s", str );
	free( str );
	
	for (i=0; i<cl->opt_num; i++)
	{
		if ( cl->options[i].value != NULL )
		{
			free( cl->options[i].value );
			cl->options[i].value = NULL;
		}
	}
	
	return 0;
}


void csvlog_close( csvlog_t *cl )
{
	int i;
	if ( cl == NULL )
	{
		return;
	}
	
	for (i=0; i < cl->opt_num; i++)
	{
		if ( cl->options[i].value != NULL )
		{
			free( cl->options[i].value );
			cl->options[i].value = NULL;
		}
		free( cl->options[i].option );
		cl->options[i].option = NULL;
	}
	free( cl->options );
	cl->options = NULL;
	fclose( cl->file );
	free( cl );
	cl = NULL;
}


